﻿using System;

using System.Collections.Generic;
using System.Text;

using Silvermoon.Visuals;
using System.Drawing;
using Silvermoon.Images;
using Silvermoon.OpenGL;

namespace Silvermoon.Controls
{
    /// <summary>
    /// Checkbox Control that has two states.
    /// </summary>
    public class CheckBox : NotifyEventControl, IInputEventBehavior
    {
        private ImageVisual checkBoxImage;
        private StringVisual stringVisual;
        private bool isChecked;
        private Texture checkedImage;
        private Texture uncheckedImage;

        public CheckBox()
            : base()
        {
            checkBoxImage = new ImageVisual();
            stringVisual = new StringVisual { LineMode = LineMode.MultiLine };
            Visuals = new Visual[] { checkBoxImage, stringVisual };
            checkedImage = SysImages.CheckedCheckBox;
            uncheckedImage = SysImages.CheckBox;
        }

        /// <summary>
        /// Gets or sets the texture used to render the checked state.
        /// </summary>
        public Texture CheckedTexture
        {
            get { return checkedImage; }
            set
            {
                if (checkedImage != value)
                {
                    checkedImage = value;
                    Invalidate(InvalidationFlag.Texture);
                }
            }
        }

        /// <summary>
        /// Gets or sets the texture used to render the unchecked state.
        /// </summary>
        public Texture UncheckedTexture
        {
            get { return uncheckedImage; }
            set
            {
                if (uncheckedImage != value)
                {
                    uncheckedImage = value;
                    Invalidate(InvalidationFlag.Texture);
                }
            }
        }


        #region props

        public string Text { get { return stringVisual.Text; } set { stringVisual.Text = value; } }

        /// <summary>
        /// Gets or sets whether the checkbox is checked.
        /// </summary>
        public bool Checked { get { return isChecked; } set { if (isChecked != value) { isChecked = value; Invalidate(InvalidationFlag.Appearance); } } }


        #endregion
        #region Methods

        private void InvalidateCheckBox()
        {
            checkBoxImage.Size = Control.ScaledSize(48, 48);
            checkBoxImage.Image = Checked ? CheckedTexture : UncheckedTexture;
        }

        protected override void OnLayout()
        {
            InvalidateCheckBox();
            checkBoxImage.Location = Control.ScaledPoint(0, (Height - checkBoxImage.Height) / 2);
            int w = checkBoxImage.Width + 3;
            stringVisual.Bounds = Control.ScaledRect(w, (Height - stringVisual.TextSize.Height) / 2, Width - w, stringVisual.Height);
            base.OnLayout();
        }

        #endregion
        #region Mouse events

        public override void OnMouseUp(MouseUpEventArgs e)
        {
            base.OnMouseUp(e);

            // we don't need double clicks on a checkbox, thus we won't have a delay for a single click:
            e.AllowDoubleClick = false;
        }

        protected override void OnClick()
        {
            Checked ^= true;
            base.OnClick();
        }
        #endregion
        #region IInputEventBehavior Members

        public void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
        {
        }

        public void OnKeyUp(System.Windows.Forms.KeyEventArgs e)
        {

        }

        public void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
        {
            switch (e.KeyChar)
            {
                case '\r':
                case ' ':
                    e.Handled = true;
                    Checked ^= true;
                    break;
            }
        }

        #endregion
    }
}
